/*
\ brief:  实现文件
\ author: 清晨与猫鱼
*/
#include <iostream>     // 引入标准输入输出库
#include <memory>       // 引入内存管理库
#include <string>       // 引入字符串库
#include <list>         // 引入list容器库

using namespace std;       // 引用标准空间

/*
\ brief:  抽象接口类
\ author: 清晨与猫鱼
*/
class Observer {
public:

/*
\ brief:  内部类设置要观察的类型
\ author: 清晨与猫鱼
*/
    class Subject {
    public:

    /*
    \ brief:   返回状态
    \ author: 清晨与猫鱼
    */
        int getState() {
            return state_;
        }

    /*
    \ brief:  设置状态
    \ author: 清晨与猫鱼
    */
        void setState(int state) {
            state_ = state;
            notifyAllObservers();       // 传递状态发送改变通知更新
        }

    /*
    \ brief: 通知全部对象
    \ author: 清晨与猫鱼
    */
        void notifyAllObservers() {
            // 遍历所有容器中所有的对象
            for (Observer* observer : observers_) {
                observer->update();
            }
        }

    /*
    \ brief:  设置要观察的对象
    \ author: 清晨与猫鱼
    */
        void attach(Observer* observer) {
            observers_.push_back(observer);
        }
    private:
        list<Observer*> observers_;     // 观察对象的list
        int state_;         // 状态
    };

    explicit Observer(Subject* subject)
        : subject_(subject) {
    }

    virtual void update() = 0;      // 接口函数，更新状态

protected:
    Subject* subject_;      // 引用 观察者类
    
};


/*
\ brief:  二进制观察者
\ author: 清晨与猫鱼
*/
class BinaryObserver 
    : public Observer {
public:

/*
\ brief:   构造的时候，将自己添加到观察者对象中
\ author: 清晨与猫鱼
*/
    explicit BinaryObserver(Subject* subject)
        : Observer(subject){ 
        subject_->attach(this);
    }

/*
\ brief:  更新状态
\ author: 清晨与猫鱼
*/
    void update() {
        cout << "Binary String: "  << subject_->getState() << endl;
    }
};


/*
\ brief:  八进制观察
\ author: 清晨与猫鱼
*/
class OctalObserver 
    : public Observer {
public:
    explicit OctalObserver(Subject* subject) 
        : Observer(subject) {
        subject_->attach(this);
    }

    void update() {
        cout << "Octal String: " << subject_->getState() << endl;
    }
};


/*
\ brief:  十六进制观察
\ author: 清晨与猫鱼
*/
class HexaObserver 
    : public Observer {
public:
    explicit HexaObserver(Subject* subject) 
        : Observer(subject) {
        subject_->attach(this);
    }

    void update() {
        cout << "Hex String: " << subject_->getState() << endl;
    }
};

